package cn.huijielong.modules.group.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import cn.huijielong.modules.group.dao.GoodsDao;
import cn.huijielong.modules.group.dao.OrderDao;
import cn.huijielong.modules.group.dao.OrderItemDao;
import cn.huijielong.modules.group.entity.GroupEntity;
import cn.huijielong.modules.group.entity.OrderEntity;
import cn.huijielong.modules.group.entity.OrderItemEntity;
import cn.huijielong.modules.group.service.OrderService;
import cn.huijielong.modules.sys.service.impl.SimpleServiceImpl;
import cn.huijielong.common.exception.VSException;
import cn.huijielong.common.utils.Query;
import cn.huijielong.common.utils.Status;



@Service("orderService")
public class OrderServiceImpl extends SimpleServiceImpl implements OrderService {
	@Autowired
	private GoodsDao goodsDao;
	@Autowired
	private OrderDao orderDao;
	@Autowired
	private OrderItemDao orderItemDao;
	
	@Override
	public OrderEntity queryObject(Long orderId){
		return orderDao.queryObject(orderId);
	}
	
	@Override
	public Page<OrderEntity> queryList(Query q){
	    Page<OrderEntity> page=PageHelper.startPage(q.getPage(), q.getLimit()).doSelectPage(()-> orderDao.queryList(q));
		return page;		
	}
	@Override
	public Page<OrderEntity> queryOrders(Query q){
		Page<Query> orders=PageHelper.startPage(q.getPage(), q.getLimit()).doSelectPage(()-> orderDao.queryOrders(q));
		List<OrderEntity> list = convertOrderList(orders);
		Page<OrderEntity> page=new Page<OrderEntity>(orders.getPageNum(),orders.getPageSize());
		page.setTotal(orders.getTotal());
		page.addAll(list);
		return page;
	}

	@Override
	public int queryTotal(Map<String, Object> map){
		return orderDao.queryTotal(map);
	}
	@Transactional
	@Override
	public void save(OrderEntity order){
		orderDao.save(order);
		List<OrderItemEntity> itemList=order.getOrderItemList();
		for(OrderItemEntity item:itemList) {
			if(item.getBuyNum()!=null && item.getBuyNum()>0) {
				item.setOrderId(order.getOrderId());
				item.setOrderNo(order.getOrderNo());
				orderItemDao.save(item);
			}
		}
	}
	@Transactional
	@Override
	public void update(OrderEntity order){
		orderDao.update(order);
		List<OrderItemEntity> oldItemList=orderItemDao.queryList(Query.empty().addParam("orderId", order.getOrderId()));
		for(OrderItemEntity item:order.getOrderItemList()) {
			boolean b=false;
			for(OrderItemEntity oldItem:oldItemList) {
				//商品ID相等
				if(item.getGoodsId().longValue()==oldItem.getGoodsId().longValue()) {
					//新的项购买数量为0，已经从订单去掉，删除该项数据
					if(item.getBuyNum()==null || item.getBuyNum()==0) {
						orderItemDao.delete(oldItem.getOrderItemId());
					}else {//修改
						orderItemDao.update(item);
						oldItemList.remove(oldItem);
					}
					b=true;
					break;
				}
			}
			//该项在原订单项中不存在
			if(!b) {
				//购买数量大于0，将该数据项保存到已有订单里
				if(item.getBuyNum()!=null || item.getBuyNum()>0) {
					item.setOrderId(order.getOrderId());
					item.setOrderNo(order.getOrderNo());
					orderItemDao.save(item);
				}
			}
		}
	}
	
	@Override
	public void delete(Long orderId){
		orderDao.delete(orderId);
	}
	
	@Override
	public void deleteBatch(Long[] orderIds){
		orderDao.deleteBatch(orderIds);
	}

	@Override
	public void updateStatus(Query param) {
		Long modifyUserId=param.getLong("userId");
		Long orderId=param.getLong("orderId");
		String status=param.getString("newStatus");
		int isUpdate=orderDao.checkAuth(modifyUserId, orderId);
		if(isUpdate==0) {
			logger.error("用户{}没有修改订单{}状态的权限，用户不是该订单对应的商户的所有者");
			throw new VSException("没有操作权限");
		}
		OrderEntity order=new OrderEntity();
		order.setOrderId(orderId);
		order.setStatus(status);
		orderDao.update(order);
		if(status.equals(Status.SUCCESS)) {
			goodsDao.updateSaleNum(orderId);
		}
		orderDao.saveOrderLog(param);
	}
	/**
	 * 订单支付成功
	 */
	@Transactional
	@Override
	public void updateSuccess(String orderNo) {
		OrderEntity orderEnity=orderDao.queryByOrderNo(orderNo);
		if(orderEnity==null) {
			logger.error("订单{}在数据库中不存在，不能做支付成功处理",orderNo);
			throw new VSException("订单不存在");
		}
		if(Status.SUCCESS.equals(orderEnity.getStatus())) {
			logger.info("订单{}状态已经改为支付成功，不用再次处理",orderNo);
			return;
		}
		if(!Status.V_1.equals(orderEnity.getStatus())) {
			logger.error("订单{}状态{}不为待支付，不能做支付成功处理",orderNo,orderEnity.getStatus());
			throw new VSException("订单状态异常");
		}
		orderEnity.setStatus(Status.SUCCESS);
		orderDao.update(orderEnity);
		goodsDao.updateSaleNum(orderEnity.getOrderId());
		
		Query param=Query.empty();
		param.addParam("orderId", orderEnity.getOrderId());
		param.addParam("userId", orderEnity.getBuyUserId());
		param.addParam("newStatus", Status.SUCCESS);
		orderDao.saveOrderLog(param);
	}
	/**
	 * 订单项到订单转换
	 * @param orders
	 * @return
	 */
	private List<OrderEntity> convertOrderList(List<Query> orders){
		
		List<OrderEntity> orderList=new ArrayList<>();
		Map<Long,OrderEntity> map=new HashMap<>();
		//把相同订单id的订单项放入到同一个订单里
		for(Query o:orders) {
			Long orderId=o.getLong("orderId");
			OrderEntity oe=map.get(orderId);
			if(oe==null) {
				oe=o.toObject(OrderEntity.class);
				String un=oe.getBuyUsername();
				if(un!=null) {
					//截取用户呢称，保留最大5个汉字，或最大10个非汉字字符
					int size=0;
					StringBuilder sb=new StringBuilder();
					char[] uns=un.toCharArray();
					for(int i=0;i<uns.length;i++) {
						if(String.valueOf(uns[i]).getBytes().length>1){
							size+=2;
						}else {
							size++;
						}
						sb.append(uns[i]);
						if(size>=10) {
							if(i<uns.length-1) {
								sb.append("...");
							}
							break;
						}
					}
					oe.setUsername_s(sb.toString());
				}
				orderList.add(oe);
				map.put(orderId, oe);
			}
			OrderItemEntity oie=o.toObject(OrderItemEntity.class);
			List<OrderItemEntity> oiList=oe.getOrderItemList();
			if(oiList==null) {
				oiList=new ArrayList<>();
				oe.setOrderItemList(oiList);
			}
			oiList.add(oie);
		}
		return orderList;
	}

	@Override
	public List<OrderEntity> queryListByGroup(Long groupId) {
		List<Query> orders=orderDao.queryListByGroup(groupId);
		return convertOrderList(orders);
	}

	@Override
	public List<String> queryOrderLogDesc(Long orderId) {
		return orderDao.queryOrderLogDesc(orderId);
	}
	@Override
	public String newOrderNo() {
		return orderDao.getOrderNo();
	}
}
